package com.nuoniu.sibanyun.service.crm.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.DateUtils;
import com.nuoniu.sibanyun.entity.bo.CrmBusinessBo;
import com.nuoniu.sibanyun.entity.crm.CrmBusiness;
import com.nuoniu.sibanyun.entity.crm.CrmCode;
import com.nuoniu.sibanyun.entity.crm.CrmCustomer;
import com.nuoniu.sibanyun.entity.crm.CrmDefineField;
import com.nuoniu.sibanyun.entity.dto.SaleFunnelDto;
import com.nuoniu.sibanyun.entity.erp.ErpNumberSet;
import com.nuoniu.sibanyun.entity.vo.CrmBusinessVo;
import com.nuoniu.sibanyun.entity.vo.EChartsFunnelVo;
import com.nuoniu.sibanyun.entity.vo.OfficeUserVo;
import com.nuoniu.sibanyun.entity.vo.SelectVo;
import com.nuoniu.sibanyun.mapper.crm.CrmBusinessMapper;
import com.nuoniu.sibanyun.mapper.crm.CrmCodeMapper;
import com.nuoniu.sibanyun.mapper.erp.ErpNumberSetMapper;
import com.nuoniu.sibanyun.service.ISysUserService;
import com.nuoniu.sibanyun.service.crm.ICrmBusinessService;
import com.nuoniu.sibanyun.service.crm.ICrmDefineFieldService;
import com.nuoniu.sibanyun.service.erp.IErpNumberSetService;
import com.nuoniu.sibanyun.userThread.DataScope;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户商机 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-07-08
 */
@Service
public class CrmBusinessServiceImpl extends ServiceImpl<CrmBusinessMapper, CrmBusiness> implements ICrmBusinessService {

    @Autowired
    private CrmCodeMapper codeMapper;
    @Autowired
    private CrmCustomerServiceImpl crmCustomerService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ICrmDefineFieldService crmDefineFieldService;
    @Autowired
    private IErpNumberSetService numberSetService;
    @Autowired
    private ErpNumberSetMapper numberSetMapper;

    @Override
    public Page<CrmBusiness> pageBusiness(Page page, CrmBusiness business) {
        UserInfo user = UserThreadLocal.get();
        return baseMapper.pageBusiness(page, business, user);
    }

    @Override
    public boolean isHaveNo(String projectNo) {
        UserInfo user = UserThreadLocal.get();
        baseMapper.isHaveNo(projectNo,user.getCompanyId());
        return false;
    }

    @Override
    public List<EChartsFunnelVo> saleFunnelStatistic(SaleFunnelDto saleFunnelDto) {
        List<EChartsFunnelVo> resultList = new ArrayList<>();
        //获取 租户自定义的
        CrmDefineField crmDefineField = crmDefineFieldService.crmDefineFieldByCode("business","saleStage");
        String defineFieldVal = crmDefineField.getVal();
        if(null == crmDefineField || StringUtils.isBlank(defineFieldVal)){
            return resultList;
        }
        //销售阶段 MAP
        HashMap<String,Integer> saleStageMap = new HashMap<>();

        String[] split = defineFieldVal.split(",");
        int defineFieldSize = split.length;
        for (int i = 0; i < defineFieldSize; i++) {
            saleStageMap.put(split[i],i);
        }
        UserInfo userInfo = UserThreadLocal.get();
        //1.获取当前用户的数据权限
        DataScope dataScope = userInfo.getDataScope();
        //最大数据权限类型
        Integer type = dataScope.getType();
        //3.如果 不是全公司权限 且 没有传入用户ID的集合
        Integer officeId = saleFunnelDto.getOfficeId();
        List<Integer> userIds = saleFunnelDto.getUserIds();
        //非公司权限的，用户ids不能为空
        if(null == userIds || userIds.size() == 0){
            if(null != officeId){
                //获取部门下的所有用户ID
                List<Integer> officeAllUserIds = sysUserService.getOfficeAllUserIds(userInfo.getCompanyId(),officeId);
                saleFunnelDto.setUserIds(officeAllUserIds);
                if(null == saleFunnelDto.getUserIds() || saleFunnelDto.getUserIds().size() == 0)return resultList;
            }else if(null != type &&  3 != type ){
                //获取 我可以统计的 所有用户（部门 + 所有自定义用户）
                List<OfficeUserVo> dataScopeOfficeUsers = sysUserService.getOfficeUserVo();
                List<Integer> userIdList = dataScopeOfficeUsers.stream().map(f->f.getUserId()).collect(Collectors.toList());
                saleFunnelDto.setUserIds(userIdList);
                if(null == saleFunnelDto.getUserIds() || saleFunnelDto.getUserIds().size() == 0)return resultList;
            }
        }
        List<CrmBusinessBo> crmBusinesses = baseMapper.saleFunnelStatistic(dataScope, saleFunnelDto);
        //设置 销售阶段下标
        crmBusinesses.stream().forEach(f->{
            Integer integer = saleStageMap.get(f.getSaleStage());
            if(null != integer){
                f.setSaleStageIndex( integer + 1);
            }else{
                f.setSaleStageIndex(1);
            }
            BigDecimal anticipatedRevenue = f.getAnticipatedRevenue();
            if(null == anticipatedRevenue){
                f.setAnticipatedRevenue(new BigDecimal(0));
            }
        });

        //1.统计所有的

        int total = crmBusinesses.size();
        BigDecimal totalDecimal = new BigDecimal(total);
        if(total == 0){
            return resultList;
        }
        double Isometric = (float) 100/ defineFieldSize;

        for (int i = 0; i < defineFieldSize; i++) {
            String s = split[i];
            EChartsFunnelVo funnelVo = new EChartsFunnelVo();
            long count =  crmBusinesses.stream().filter(f -> f.getSaleStageIndex() > saleStageMap.get(s)).count();
            BigDecimal totalMoney = crmBusinesses.stream().filter(f -> f.getSaleStageIndex() > saleStageMap.get(s)).map(CrmBusinessBo::getAnticipatedRevenue).reduce(BigDecimal.ZERO, BigDecimal::add);
            funnelVo.setName(s);
            funnelVo.setNumber(count);
            funnelVo.setMoney(totalMoney);
            funnelVo.setValue(100 - Isometric * i);
            BigDecimal bigDecimal = new BigDecimal(count * 100);
            BigDecimal setScale = bigDecimal.divide(totalDecimal,2, BigDecimal.ROUND_HALF_UP);
            funnelVo.setPercentage(setScale );
            resultList.add(funnelVo);
        }
        return resultList;
    }


    /**
     * 获取商机编码
     */
    public String getHeadCode(Integer companyId) {
        String head = "SJ";
        if(companyId != null) {
            CrmCode code = codeMapper.getCode(companyId, "商机编码");
            return code.getCurrentCode();
        }
        return head;
    }

    public String getBusinessNo(Integer companyId) {
        ErpNumberSet numberSet = numberSetMapper.getByCode("Business", companyId, 0);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getNewestCode(companyId, dateStr);
        return numberSetService.getCode(numberSet, code);
    }

    @Override
    public void updateCode(String currentCode) {
        UserInfo userInfo = UserThreadLocal.get();
        baseMapper.updateCode(currentCode, userInfo.getCompanyId());
    }

    @Override
    public CrmBusinessVo detailById(Integer id) {
        return baseMapper.detailById(id);
    }

    @Override
    public List<CrmBusiness> listNoDistributeCrmBusiness() {
        UserInfo userInfo = UserThreadLocal.get();
        List<CrmBusiness> crmBusinesses = baseMapper.listNoDistributeCrmBusiness(userInfo.getCompanyId());
        return crmBusinesses;
    }

    @Override
    public List<CrmBusiness> listActivityBusiness(Integer activityId) {
        UserInfo userInfo = UserThreadLocal.get();
        List<CrmBusiness> crmBusinesses = baseMapper.listActivityBusiness(activityId, userInfo.getCompanyId());
        return crmBusinesses;
    }

    @Override
    public void clearActivityAndBusiness(List<Integer> activityIds) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.in("activity_id",activityIds);
        updateWrapper.set("activity_id",null);
        boolean update = update(updateWrapper);
        if(!update){
            throw new NuoNiuException("清除市场活动和商机关系失败");
        }
    }

    @Override
    public void clearActivityAndBusinessByBusinessIds(List<Integer> businessIds, Long activityId) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("activity_id",activityId);
        updateWrapper.in("id",businessIds);
        updateWrapper.set("activity_id",null);
        boolean update = update(updateWrapper);
        if(!update){
            throw new NuoNiuException("清除市场活动和商机关系失败");
        }
    }

    @Override
    public void setActivityAndBusiness(List<Integer> businessIds, Long activityId) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.in("id",businessIds);
        updateWrapper.isNull("activity_id");
        updateWrapper.set("activity_id",activityId);
        boolean update = update(updateWrapper);
        if(!update){
            throw new NuoNiuException("设置市场活动和商机关系失败");
        }
    }


}
